/************************************************************************
 * AIDE/Examples - Automata Identification Engine
 * Copyright (C) 2012-2013 Ali Khalili (khalili_DOT_ir_@SIGN_gmail_DOT_com)
 * **********************************************************************
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License (LGPL) published 
 * by the Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version. This program is distributed without any
 * warranty. See the GNU Lesser General Public License for more details. 
 * ***********************************************************************
 * File         :     
 * Description  :     
 * Change log   :     	-Date:  Change
 ************************************************************************/
﻿using System;
using System.Collections.Generic;
using SMLib.Automata.Base;
using SMLib.Automata.DFA;
using AIDE.OfflineAlgo.DFAs;


namespace LearningApp.Examples
{
    /// <summary>
    /// This aims to show how to use an offline DFA learning
    /// </summary>
    public class OfflineDFALearning
    {
        /// <summary>
        /// The main funtion to run the example
        /// </summary>
        public static void RunExample()
        {
            //* we define the alphabet
            Alphabet alph = new Alphabet();

            List<Word> sPos, sNeg;
            sPos = new List<Word>();
            sNeg = new List<Word>();

            int examlpe = 2;
            //* there are different examples (taken from literature)
            switch (examlpe)
            {
                case 0:
                    //* [example is from "IDENTIFYING  REGULAR  LANGUAGES  IN  POLYNOMIAL  TIME (1992)"]
                    ISymbol zero = new StringSymbol("0"), one = new StringSymbol("1");
                    alph.AddSymbols(zero, one);
                    sPos.Add(new Word().AddSymbols(zero, one, one));//011
                    sPos.Add(new Word().AddSymbols(one, zero, one));//101

                    sNeg.Add(new Word().AddSymbols(one));//1
                    break;
                case 1:
                    //* [example is from "Grammatical_Inference_Learning Automata and Grammars (2010)" page ]
                    ISymbol a = new StringSymbol("a"), b = new StringSymbol("b");
                    alph.AddSymbols(a, b);
                    sPos.Add(new Word().AddSymbols(a, a, a));//aaa
                    sPos.Add(new Word().AddSymbols(a, a, b, a));//aaba
                    sPos.Add(new Word().AddSymbols(b, b, a));//bba
                    sPos.Add(new Word().AddSymbols(b, b, a, b, a));//bbaba

                    sNeg.Add(new Word().AddSymbols(a));//a
                    sNeg.Add(new Word().AddSymbols(b, b));//bb
                    sNeg.Add(new Word().AddSymbols(a, a, b));//aab
                    sNeg.Add(new Word().AddSymbols(a, b, a));//aba
                    break;
                case 2:
                    //* [example is from "Grammatical_Inference_Learning Automata and Grammars (2010)" exercise 12.8]
                    a = new StringSymbol("a"); b = new StringSymbol("b");
                    //S+={a,abb,bab,babbb}
                    //S−={ab,bb,aab,b,aaaa,babb}.
                    alph.AddSymbols(a, b);
                    sPos.Add(new Word().AddSymbols(a));//a
                    sPos.Add(new Word().AddSymbols(a, b, b));
                    sPos.Add(new Word().AddSymbols(b, a, b));
                    sPos.Add(new Word().AddSymbols(b, a, b, b, b));

                    sNeg.Add(new Word().AddSymbols(a, b));
                    sNeg.Add(new Word().AddSymbols(b, b));
                    sNeg.Add(new Word().AddSymbols(a, a, b));
                    sNeg.Add(new Word().AddSymbols(b));
                    sNeg.Add(new Word().AddSymbols(a, a, a, a));
                    sNeg.Add(new Word().AddSymbols(b, a, b, b));
                    break;
            }

            //* create the learner
            RPNI learner = new RPNI(alph, sPos, sNeg);
            //* and learn
            DFA conj = learner.Learn();
            //* Use GLEE? if yes, we can visualize the conjecture
            //AIDE.Automata.Utils.AutomataUtils.DrawAutomata(conj);
			
			//* if not? we can save it in a dot file like this:
			SMLib.Interoperability.DOT.DotHelper_DFA.WriteToDot("exampleDFA.dot",conj);
			
        }
    }
}
